package org.example.lock;

import java.util.concurrent.locks.*;
import java.util.concurrent.atomic.*;
import java.util.*;

public class SyncWriter {
    private static final int TOTAL = 5; // 由A线程决定的总写入次数
    private static final List<Character> result = Collections.synchronizedList(new ArrayList<>());
    private static final AtomicInteger current = new AtomicInteger(0);
    private static final AtomicBoolean termination = new AtomicBoolean(false);
    private static final Lock lock = new ReentrantLock();
    private static final Condition aCond = lock.newCondition();
    private static final Condition bCond = lock.newCondition();
    private static final Condition cCond = lock.newCondition();

    public static void main(String[] args) throws InterruptedException {
        Thread a = new Thread(SyncWriter::threadA);
        Thread b = new Thread(SyncWriter::threadB);
        Thread c = new Thread(SyncWriter::threadC);
        a.start();
        b.start();
        c.start();

        Thread.sleep(10);
        // 初始触发A线程
        lock.lock();
        System.out.println("main 获取锁");
        try {
            aCond.signal();
        } finally {
            lock.unlock();
            System.out.println("main 释放锁");
        }

        a.join();
        b.join();
        c.join();
        System.out.println(result);
    }

    private static void threadA() {
        while (!termination.get()) {
            lock.lock();
            System.out.println("threadA 获取锁");
            try {
                aCond.await();
                System.out.println("threadA 突破await");
                if (termination.get()) break;
                result.add('a');
                int next = current.incrementAndGet();
                if (next >= TOTAL) termination.set(true);
                bCond.signal();
            } catch (InterruptedException e) {
                e.printStackTrace();
                Thread.currentThread().interrupt();
            } finally {
                lock.unlock();
                System.out.println("threadA 释放锁");
            }
        }

        System.out.println("threadA over");
    }

    private static void threadB() {
        while (!termination.get()) {
            lock.lock();
            System.out.println("threadB 获取锁");
            try {
                bCond.await();
                System.out.println("threadB 突破await");
                result.add('l');
                cCond.signal();
                if (termination.get()) break;
            } catch (InterruptedException e) {
                e.printStackTrace();
                Thread.currentThread().interrupt();
            } finally {
                lock.unlock();
                System.out.println("threadB 释放锁");
            }
        }

        System.out.println("threadB over");
    }

    private static void threadC() {
        while (!termination.get()) {
            lock.lock();
            System.out.println("threadC 获取锁");
            try {
                cCond.await();
                System.out.println("threadC 突破await");
                result.add('i');
                aCond.signal();
                if (termination.get()) break;
            } catch (InterruptedException e) {
                e.printStackTrace();
                Thread.currentThread().interrupt();
            } finally {
                lock.unlock();
                System.out.println("threadC 释放锁");
            }
        }

        System.out.println("threadC over");
    }
}